/*
 * TThreadSafeQueue.h
 *
 *  Created on: 28.08.2011
 *      Author: Kirill Blinov
 *      Copyright: LGPL
 */

#ifndef TTHREADSAFEQUEUE_H_
#define TTHREADSAFEQUEUE_H_

#include <boost/thread.hpp>

/*
 * Thread safe non priority queue
 */
template< class MessageType  >
class TThreadSafeQueue
{
private:
	boost::mutex rwMutex;
	MessageType* messages;

	unsigned int queueSize;
	unsigned int messageCount;
	unsigned int writeCursor;
	unsigned int readCursor;

	static const unsigned int DEFAULT_QUEUE_SIZE = 25;
public:
	TThreadSafeQueue(): queueSize( DEFAULT_QUEUE_SIZE ), messageCount(0), writeCursor(0), readCursor(0)
	{
		messages = new MessageType[queueSize];
	}

	TThreadSafeQueue( const unsigned int QueueSize ): queueSize( QueueSize ), messageCount(0), writeCursor(0), readCursor(0)
	{
		messages = new MessageType[queueSize];
	}
	virtual ~TThreadSafeQueue()
	{
		delete[]  messages;
	}

	bool Send( MessageType Message )
	{
		bool Result = ( messageCount < queueSize );
		if ( Result )
		{
			boost::mutex::scoped_lock lock( rwMutex ); // When lock distroy rwMutex will be freed
			messages[writeCursor] = Message;
			writeCursor = ( ( writeCursor + 1 ) % (queueSize) );
			messageCount++;
		}
		return Result;
	}

	bool Receive( MessageType *OutMessage )
	{
		bool Result = ( messageCount > 0 );
		if ( Result )
		{
			boost::mutex::scoped_lock lock( rwMutex ); // When lock distroy rwMutex will be freed
			*OutMessage = messages[readCursor];
			readCursor = ( ( readCursor + 1 ) % (queueSize) );
			messageCount--;
		}
		return Result;
	}
};

#endif /* TTHREADSAFEQUEUE_H_ */
